package com.skyz.base.dialog;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatDialogFragment;
import androidx.fragment.app.FragmentManager;

public abstract class BaseDialogFragment extends AppCompatDialogFragment {

    protected final String TAG = getClass().getSimpleName();

    //当前dialogFragment 的Context对象实例
    protected Context mContext;

    //当前dialogFragment所持有的dialog对象是否能取消
    private boolean mDialogCancelable = true;

    //当前dialogFragment所持有的dialog对象是否能通过触摸外部取消
    private boolean mDialogCanceledOnTouchOutside = true;

    private View mDialogContentView;

    //解决跳页之后返回动画重复执行的问题
    private boolean mInit = false;
    private int mWindowAnimations = 0;

    //请求关闭，可能已经请求关闭了，但由于dismiss进入异常，下次读到这个标记位直接关闭
    private boolean mShowInScreen = false;
    private boolean mRequestDismiss = false;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //onCreateView 方法可能会被多次调用（Fragment 生命周期)
        mContext = inflater.getContext();

        if (mDialogContentView == null) {
            initContentView(inflater, container, savedInstanceState);
            initData(savedInstanceState);
        } else {
            ViewGroup viewGroup = (ViewGroup) mDialogContentView.getParent();
            if (viewGroup != null) {
                viewGroup.removeView(mDialogContentView);
            }
        }
        return mDialogContentView;
    }

    private void initContentView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //获取到 子类Activity 的布局id，并将布局加载进来
        int layoutId = getLayoutId();
        if (layoutId == 0) {
            Log.w(TAG, "You may forget to fill in the layout id!");
            return;
        }
        mDialogContentView = inflater.inflate(layoutId, container, false);
        onLayoutInflated(mDialogContentView);
    }

    private void makeDialogFullScreen() {
        Dialog dialog = getDialog();
        if (dialog == null) {
            return;
        }
        Window window = dialog.getWindow();
        if (window == null) {
            return;
        }
        window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
    }

    private void initDialogCancelable() {
        Dialog dialog = getDialog();
        if (dialog == null) {
            return;
        }
        dialog.setCancelable(mDialogCancelable);
        dialog.setCanceledOnTouchOutside(mDialogCanceledOnTouchOutside);
    }

    @Override
    public void onStart() {
        super.onStart();
        mShowInScreen = true;
        if (mRequestDismiss) {
            dismiss();
        }
        if (!mInit) {
            makeDialogFullScreen();
            initDialogCancelable();
            initDialogParams();
            mInit = true;
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        Dialog dialog = getDialog();
        if (dialog == null) {
            return;
        }
        Window window = dialog.getWindow();
        if (window == null) {
            return;
        }
        new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
            @Override
            public void run() {
                window.setWindowAnimations(mWindowAnimations);
            }
        }, 50);
    }

    @Override
    public void onStop() {
        mShowInScreen = false;
        super.onStop();
        Dialog dialog = getDialog();
        if (dialog == null) {
            return;
        }
        Window window = dialog.getWindow();
        if (window == null) {
            return;
        }
        window.setWindowAnimations(0);
    }

    private void initDialogParams() {
        Dialog dialog = getDialog();
        if (dialog == null) {
            return;
        }
        Window window = dialog.getWindow();
        if (window == null) {
            return;
        }
        WindowManager.LayoutParams layoutParams = window.getAttributes();

        WindowManager.LayoutParams temp = initLayoutParams(layoutParams);
        if (temp != null) {
            layoutParams = temp;
        } else {
            layoutParams.gravity = Gravity.CENTER;
            layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        }
        mWindowAnimations = layoutParams.windowAnimations;
        window.setAttributes(layoutParams);
    }

    /**
     * 根据实际情况动态修改Dialog是否能取消{@link #mDialogCancelable}.
     *
     * @param flag true:能 false:不能
     */
    protected void setDialogCancelable(boolean flag) {
        if (!flag && mDialogCanceledOnTouchOutside) {
            mDialogCanceledOnTouchOutside = false;
        }
        mDialogCancelable = flag;
        initDialogCancelable();
    }

    /**
     * 根据实际情况动态修改Dialog是否能通过触摸外部取消{@link #mDialogCanceledOnTouchOutside}.
     *
     * @param flag true:能 false:不能
     */
    protected void setDialogCanceledOnTouchOutside(boolean flag) {
        if (flag && !mDialogCancelable) {
            mDialogCancelable = true;
        }
        mDialogCanceledOnTouchOutside = flag;
        initDialogCancelable();
    }

    protected abstract int getLayoutId();

    protected abstract void onLayoutInflated(View view);

    protected abstract WindowManager.LayoutParams initLayoutParams(WindowManager.LayoutParams layoutParams);

    protected abstract void initData(Bundle savedInstanceState);

    @Override
    public void show(@NonNull FragmentManager manager, @Nullable String tag) {
        if (manager.isStateSaved() || manager.isDestroyed()) {
            Log.w(TAG, "show dialog fragment in a wrong state");
            return;
        }
        super.show(manager, tag);
    }

    @Override
    public void dismiss() {
        mRequestDismiss = true;
        if (mShowInScreen) {
            try {
                super.dismiss();
            } catch (Exception e) {
                Log.e(TAG, e.getMessage());
                try {
                    super.dismissAllowingStateLoss();
                } catch (Exception e1) {
                    Log.e(TAG, e1.getMessage());
                }
            }
        }
    }

    public boolean isShowing() {
        if (getDialog() != null && getDialog().isShowing() && !isRemoving()) {
            return true;
        } else {
            return false;
        }
    }
}
